package sdk.webview.fmc.com.fmcsdk.service;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.NonNull;

import com.google.gson.Gson;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.File;
import java.util.List;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
import sdk.webview.fmc.com.fmcsdk.BuildConfig;
import sdk.webview.fmc.com.fmcsdk.base.BaseData;
import sdk.webview.fmc.com.fmcsdk.base.UserApi;
import sdk.webview.fmc.com.fmcsdk.bean.AgreementBean;
import sdk.webview.fmc.com.fmcsdk.bean.UploadImage;
import sdk.webview.fmc.com.fmcsdk.bean.UploadVideoBean;
import sdk.webview.fmc.com.fmcsdk.bean.User;
import sdk.webview.fmc.com.fmcsdk.check.HideLoadEvent;
import sdk.webview.fmc.com.fmcsdk.db.DBManager;
import sdk.webview.fmc.com.fmcsdk.db.IMAGE;
import sdk.webview.fmc.com.fmcsdk.db.Record;
import sdk.webview.fmc.com.fmcsdk.db.VIDEO;
import sdk.webview.fmc.com.fmcsdk.util.Constant;
import sdk.webview.fmc.com.fmcsdk.util.DesUtil;
import sdk.webview.fmc.com.fmcsdk.util.FastClickHelper;
import sdk.webview.fmc.com.fmcsdk.util.HandleJsEvent;
import sdk.webview.fmc.com.fmcsdk.util.HttpsUtils;
import sdk.webview.fmc.com.fmcsdk.util.ImageUtils;
import sdk.webview.fmc.com.fmcsdk.util.KLog;
import sdk.webview.fmc.com.fmcsdk.util.PreferencesHelper;
import sdk.webview.fmc.com.fmcsdk.util.ToastUtils;
import sdk.webview.fmc.com.fmcsdk.util.UpLoadEvent;
import sdk.webview.fmc.com.fmcsdk.util.Url;
import sdk.webview.fmc.com.fmcsdk.util.UserHelper;
import sdk.webview.fmc.com.fmcsdk.util.Utility;
import sdk.webview.fmc.com.fmcsdk.util.XLog;
import sdk.webview.fmc.com.fmcsdk.util.retrofit2.observer.ApiFactory;
import sdk.webview.fmc.com.fmcsdk.util.retrofit2.observer.ResponseTransformer;
import sdk.webview.fmc.com.fmcsdk.util.retrofit2.subscriber.ResponseSubscriber;

/**
 * Created by ydm on 2017/12/27.
 * 该服务用来监听网络，如果有网络的时候数据库里离线保存的图片上传到服务器
 * 离线视频也要上传到服务器
 */

public class UploadImageService extends Service {
    private PowerManager.WakeLock wakeLock;
    private SharedPreferences defaultSharedPreferences;
    //避免多次广播
    private static int lastType = -1;
    //图片的数量
    private int imageListSize = 0;

    @Override
    public void onCreate() {
        super.onCreate();
      //  EventBus.getDefault().register(this);
        XLog.i("UploadImageService onCreate");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        XLog.i("UploadImageService onStart");
        defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        //手机息屏时候唤醒CPU发送数据，不然过一会会中断
        wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LocationService.class.getName());
        wakeLock.acquire();
        /**网络监听广播*/
        registerReceiver(mConnectivityChanged, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
        return START_REDELIVER_INTENT;
    }

    /**
     * 查询数据库是否有图片
     *
     * @param iswifiup 是否为wifi连接状态
     */
    List<Record> imagList;
    private boolean iswifiupImage = false;

    List<Record> vedioList;
    private boolean iswifiupVideo = false;

    /**
     * 查询数据库是否有图片和视频，并开启心跳
     *
     * @param iswifiupim
     * @param iswifiupvi
     */
    private void startQueryFile(boolean iswifiupim, boolean iswifiupvi) {
        UploadFileManager.getInstance().startQueryFile(this, iswifiupim, iswifiupvi, null);
//        iswifiupImage = iswifiupim;
//        iswifiupVideo = iswifiupvi;
//
//        imagList = DBManager.getDBManager(this).getRecords(IMAGE.TABLE_NAME, null);
//        vedioList = DBManager.getDBManager(this).getRecords(VIDEO.TABLE_NAME, null);
//
//        allFileSize = imagList.size() + vedioList.size(); //要上传的文件的整的数目
//        mCurMeiZuNum = 10; //当前每一组文件的数目 的默认值 根据后端字典来
//
//        if (imagList.size() > 0) {
//            imageListSize = imagList.size();
//            if (iswifiupImage) {
//                // 开始心跳
//                initMeiyizudeNum();
//                xintiaoHand();
//            }
//        } else {
//            if (vedioList.size() > 0) {
//                if (iswifiupVideo) {
//                    // 开始心跳
//                    initMeiyizudeNum();
//                    xintiaoHand();
//                }
//            }
//        }
    }


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


    /**
     * 网络监听广播
     */
    private BroadcastReceiver mConnectivityChanged = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            intentNew = intent;
            KLog.e("imgList", "222");
            startnetWork();

        }
    };
    private Intent intentNew;

    private boolean isNetOne=true;//有网后只是请求一次

    private boolean isOne = true;


    private Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                KLog.e("22222");
                SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
                final String address = sharedPrefs.getString(Constant.BASE_ADDRESS_URL, "");
                List<String> list = HttpsUtils.getIps(address);
                String ip = "www.baidu.com";
                if (!HttpsUtils.isEmpty(list)) {
                    ip = list.get(0);
                    //Log.e("ip11111", ip);
                }
                Process ipProcess = null;// -c 次数 -w 超时
                ipProcess = Runtime.getRuntime().exec("ping -c 1 " + ip);
                //exitValue==0网络可用，否则网络不可用
                int exitValue = ipProcess.waitFor();
                ipProcess.destroy();
                Message message = new Message();
                message.arg1 = exitValue;
                // handler.sendMessageDelayed(message, 2000);
                if (exitValue == 0) {
                    EventBus.getDefault().post(new NetWorkEvent(1));

                    //Constant.isHaveNet=true;
                    if(isNetOne){
                        isNetOne=false;
                        startImg();
                    }
                    isOne = true;
                    backgroundHandler.postDelayed(thread, 5000);
                } else {
                    EventBus.getDefault().post(new NetWorkEvent(0));
                    EventBus.getDefault().post(new HideLoadEvent());
                    //Constant.isHaveNet=false;
                    isNetOne=true;
                    if (isOne) {
                        EventBus.getDefault().post(new HandleJsEvent(3008, ""));
                        isOne = false;
                    }
                    backgroundHandler.postDelayed(thread, 1000);
                }

                KLog.e("isZero1111", "1111---" + exitValue);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
    private Handler backgroundHandler;

    private void startnetWork() {
        // handler.postDelayed(thread, 2000);
        HandlerThread handlerThread = new HandlerThread("BackgroundThread");
        handlerThread.start();
        Looper looper = handlerThread.getLooper();
        backgroundHandler = new Handler(looper);
        KLog.e("22222");
        backgroundHandler.postDelayed(thread, 1000);
    }


    public void startImg() {
        if (!FastClickHelper.isFastClick()) return;
        NetworkListenerService service=new NetworkListenerService();
        service.checkNetworkAndUpload();
        try {
            NetworkInfo info = (NetworkInfo) intentNew.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
            boolean hasConnectivity = (info != null && info.isConnected()) ? true : false;
            int netType = info.getType();
            //Log.e("1111111", "hasConnectivity" + hasConnectivity);
                //查询数据库是否有图片
                //判断用户是否为仅wifi情况下上传图片
                boolean wifi_up = defaultSharedPreferences.getBoolean(Constant.WIFI_UP, false);
                //没有设置仅wifi上传
                if (!wifi_up) {
                    startQueryFile(true, true);
                } else {
                    //设置了仅wifi上传
                    if (info.getType() == ConnectivityManager.TYPE_WIFI) {
                        startQueryFile(true, true);
                    } else {
                        startQueryFile(true, true);
                    }
                }
                //避免第二次相同广播
                if (lastType == netType) {
                    return;
                }
                //保存本次网络状态
                lastType = netType;
        } catch (Exception e) {
        }
    }
    private void deleteFiles(File dir) {
        if (dir == null || !dir.exists() || dir.listFiles() == null) return;
        for (File file : dir.listFiles()) {
            if (file.isDirectory()) {
                deleteFiles(file);
            } else {
                file.delete();
            }
        }
        dir.delete();
    }

    private void uploadImageNew(final Record record) {
        //Log.e("11111111","222222222");
        File files = new File(ImageUtils.getH5ImagePath(record.getString("imageUrl"), UploadImageService.this).replace("jpg", "jpeg"));
        if (!files.exists()) {
            return;
        }
        RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), files);
        RequestBody typeBody = RequestBody.create(MediaType.parse("multipart/form-data"), record.getString(IMAGE.TIMESTAMP));
        RequestBody timeBody = RequestBody.create(MediaType.parse("multipart/form-data"), System.currentTimeMillis()+"");//,+""

        ApiFactory.getFactory().create(UserApi.class).uploadImgForClient(defaultSharedPreferences.getString(Constant.BASE_ADDRESS_URL, "") + Url.UPLOAD_IMG, Url.XMLHTTPREQUEST, UserHelper.getToken(), requestBody, typeBody,timeBody)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<UploadImage>() {
                    @Override
                    public void onCompleted() {
                        XLog.i("uploadImage result：" + "onCompleted", UploadImageService.this);
//                        uploadCallBack(record.getString("timeStamp"), "reload123_android:成功", "", null);
                    }

                    @Override
                    public void onError(Throwable e) {
//                        uploadCallBack(record.getString("ownerId"), "reload123_android:失败-->" + e.getClass().getName(), "dos", record);
                        XLog.i("uploadImage result：" + "timeStamp:" + e, UploadImageService.this);
                        mHandler.sendEmptyMessage(101); //上传失败
                    }

                    @Override
                    public void onNext(UploadImage result) {
                        uploadFilesService(record, result.getRecord().get(0).getId(), 0);
                    }
                });
    }

    /**
     * 上传图片到客户端
     */

    private void xintiaoHand() {
        Message message = new Message();
        message.what = 0;
        mHandler.sendMessageDelayed(message, jiangeXintiaoTime());
    }


    /**
     * 图片上传到服务器
     */
    private void uploadFilesService(final Record record, String id, final int type) {
        ApiFactory.getFactory().create(UserApi.class).uploadImgForServer(defaultSharedPreferences.getString(Constant.BASE_ADDRESS_URL, "") + Url.UPLOAD_FILES_SERVICE, Url.XMLHTTPREQUEST, UserHelper.getToken(), UserHelper.getToken(), record.getString("ownerId"), record.getString("ownerObject"), record.getString("ownerType"), id)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<BaseData>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        mHandler.sendEmptyMessage(101); //上传失败
                        XLog.i("uploadFilesService result：" + "onError:" + e, UploadImageService.this);
                    }

                    @Override
                    public void onNext(BaseData result) {
                        if (type == 0) {
                            //成功后删除图片,缩略图和数据库保存的数据
                            Utility.deleteH5Image(UploadImageService.this, record);
                            mHandler.sendEmptyMessage(100); //上传image成功
                        } else {
                            //成功后删除视频数据库保存的数据
                            DBManager.getDBManager(UploadImageService.this).delete(record);
                            mHandler.sendEmptyMessage(200); //上传vidoe成功
                        }
                    }
                });
    }


    /**
     * 上传视频到客户端
     */
    private void uploadVideo(final Record record) {
        File files = new File(record.getString(VIDEO.VIDEOLOCALURL));
        if (!files.exists()) {
            return;
        }
        RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), files);
        RequestBody timeBody = RequestBody.create(MediaType.parse("multipart/form-data"), System.currentTimeMillis()+"");//,+""

        RequestBody typeBody = RequestBody.create(MediaType.parse("multipart/form-data"), record.getString(VIDEO.TIMESTAMP));
        ApiFactory.getFactory().create(UserApi.class).uploadVideo(defaultSharedPreferences.getString(Constant.BASE_ADDRESS_URL, "") + Url.UPLOAD_VIDEO, Url.XMLHTTPREQUEST, UserHelper.getToken(), requestBody, typeBody,timeBody)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<UploadVideoBean>() {
                    @Override
                    public void onCompleted() {
                        XLog.i("uploadImage result：" + "onCompleted", UploadImageService.this);
                    }

                    @Override
                    public void onError(Throwable e) {
                        XLog.i("uploadImage result：" + "onError:" + e, UploadImageService.this);
                        mHandler.sendEmptyMessage(101); //上传失败
                    }

                    @Override
                    public void onNext(UploadVideoBean result) {
                        uploadFilesService(record, result.getRecord().getId() + "", 1);
                    }
                });
    }


    /**
     * 心跳
     */
    private void serverNginxStatus() {
        re_UploadImage();
//        ApiFactory.getFactory().create(UserApi.class).serverNginxStatus(defaultSharedPreferences.getString(Constant.BASE_ADDRESS_URL, "") + Url.SERVER_NGINXSTATUS)
//                .subscribeOn(Schedulers.io())
//                .observeOn(AndroidSchedulers.mainThread())
//                .subscribe(new Subscriber<BaseData>() {
//                    @Override
//                    public void onCompleted() {
//
//                    }
//
//                    @Override
//                    public void onError(Throwable e) {
//                        Log.e("HttpLogging", "onError-------------->");
//                        XLog.i("baseData:" + e);
//                        xintiaoHand();
//                    }
//
//                    @Override
//                    public void onNext(BaseData result) {
//                        if (!"200".equals(result.getStatus())) {
//                            xintiaoHand();
//                        } else {
//                            //开始上传
//                            re_UploadImage();
//                        }
//                    }
//                });
    }


    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0:
                    serverNginxStatus();
                    break;

                case 200: //上传video成功
                    //开启下一组的上传
                    mCurUploadImageSuccessIndex++;
                    mHasSunccessNum++;
                    meiyizudeNum(); //重新计算每一组的数量
                    if (mCurUploadImageSuccessIndex < vedioList.size() - 1) {  //开始下一组的文件上传
                        if (mCurUploadImageSuccessIndex == nextTimeImageIndex) {
                            startUploadVideo();
                        }
                    }
                    break;
                case 100: //上传image成功
                    //开启下一组的上传
                    mCurUploadImageSuccessIndex++;
                    mHasSunccessNum++;
                    meiyizudeNum(); //重新计算每一组的数量
                    Log.e("shuchang1", "上传成功，当前文件的下标--->" + mCurUploadImageSuccessIndex);
                    if (mCurUploadImageSuccessIndex < imagList.size() - 1) {
                        if (mCurUploadImageSuccessIndex == nextTimeImageIndex) {
                            startUploadImage();
                        }
                    } else {
                        re_UploadVideo();
                    }
                    break;
                case 101: //上传失败
                    //重新心跳
                    cishu = 1;
                    mHasSunccessNum = 0;
                    meiyizudeNum(); //重新计算每一组的数量
                    serverNginxStatus();
                    break;
            }
        }
    };


    @Override
    public void onDestroy() {
        super.onDestroy();
        if (backgroundHandler != null) {
            backgroundHandler.removeCallbacksAndMessages(null);
            backgroundHandler = null;
        }
        if (wakeLock != null) {
            wakeLock.release();
            wakeLock = null;
        }
        if (mConnectivityChanged != null){
            unregisterReceiver(mConnectivityChanged);
        }

    }


    /**
     * 心跳的间隔时间
     * 第一次2s，第二次4s，第三次8s，第n次 2的n次方（间隔最大值由后端字典提供，默认3600s）
     * 上传成功以后，重置间隔时间，再回到第一次2s
     *
     * @return
     */
    private long jiangeTime = 2;
    private int cishu = 1; //执行心跳的次数

    private long jiangeXintiaoTime() {
        jiangeTime = 1 << cishu;
        cishu++;
        int maxJiange = Integer.parseInt(UserHelper.getSysKeyDescValueBycode("OFFLINE_HEART_INTERVAL"));
        if (jiangeTime >= maxJiange) {
            Log.e("shuchang1", "心跳的间隔时间---->" + maxJiange);
            return maxJiange * 1000;
        } else {
            Log.e("shuchang1", "心跳的间隔时间---->" + jiangeTime);
            return jiangeTime * 1000;
        }

    }

    /**
     * 重新上传离线的剩余的图片
     * 先上传图片
     * 如果全部上传成功，就继续上传，如果没有全部成功那么重新发起心跳 并且每一组的数量 优化
     */
    private int lastTimeImageIndex = -1;//记录上一次上传成功之后最后一次的下标
    private int nextTimeImageIndex = -1;//记录这一组上传成功之后最后一次的下标
    private int mCurUploadImageSuccessIndex = -1; //记录当前上传成功的下标,当数值为lastTimeImageIndex时，开始下一组的上传

    private void startUploadImage() {
        lastTimeImageIndex = nextTimeImageIndex;

        if (lastTimeImageIndex < imagList.size() - 1) {
            nextTimeImageIndex = lastTimeImageIndex + mCurMeiZuNum;

            if (nextTimeImageIndex >= imagList.size() - 1) {
                nextTimeImageIndex = imagList.size() - 1;
            }
            for (int i = 0; i < imagList.size(); i++) {
                if (i > lastTimeImageIndex && i < nextTimeImageIndex + 1) {
                    uploadImageNew(imagList.get(i));
                }
            }
        }

    }

    private void re_UploadImage() {

        lastTimeImageIndex = -1;
        mCurUploadImageSuccessIndex = -1;

        imagList = DBManager.getDBManager(this).getRecords(IMAGE.TABLE_NAME, null);
        KLog.e(imagList.size());

        if (imagList.size() > 0) {
            startUploadImage();
        } else {
            re_UploadVideo();
        }
    }

    /**
     * 重新上传离线的剩余的视频
     * 当所有的离线图片全部上传完成之后 再上传视频
     */
    private void startUploadVideo() {
        lastTimeImageIndex = nextTimeImageIndex;

        if (lastTimeImageIndex < vedioList.size() - 1) {
            nextTimeImageIndex = lastTimeImageIndex + mCurMeiZuNum;

            if (nextTimeImageIndex >= vedioList.size() - 1) {
                nextTimeImageIndex = vedioList.size() - 1;
            }
            for (int i = 0; i < vedioList.size(); i++) {
                if (i > lastTimeImageIndex && i < nextTimeImageIndex + 1) {
                    uploadVideo(vedioList.get(i));
                }
            }
        }

    }


    private void re_UploadVideo() {

        lastTimeImageIndex = -1;
        mCurUploadImageSuccessIndex = -1;

        vedioList = DBManager.getDBManager(this).getRecords(VIDEO.TABLE_NAME, null);

        if (vedioList.size() > 0) {
            if (iswifiupVideo) {
                startUploadVideo();
            }
        }
    }

    /**
     * 上传的每一组的数目（即每一次上传的数目）
     * <p>
     * 第一次的每一组的数目计算方式：总数除以A，如果结果大于B，按B算
     * A，B 由 后端字典提供，默认是A默认为10，B默认为10
     * 寻找最佳的文件数量 ：第一次的每一组的数量/2，直到1
     * <p>
     * type='OFFLINE_FILE_DIVIDE'
     * 文件除数：code='FILE_DIVIDE_NUM'  每组的文件数目
     * 总组数：code='FILE_DIVIDE_GROUPS'
     * 离线心跳间隔上限：code='OFFLINE_HEART_INTERVAL'
     */
    private int allFileSize = 0; //要上传的文件的整的数目
    private int mCurMeiZuNum = 10; //当前每一组文件的数目
    private int mStartMeizuNum = 10;//记录最开始的时候的每组的文件数目（也即是第一次的）
    private int mHasSunccessNum = 0;// 记录根据当前的组上传，成功的数目,连续10次传1个没问题，每次的文件数量传2个，连续10次2个没问题，文件数量传4个，直到最初的每组文件数

    private void meiyizudeNum() {
        if (mHasSunccessNum == 10) {
            if (mCurMeiZuNum < mStartMeizuNum) {
                mCurMeiZuNum = mCurMeiZuNum * 2;
                if (mCurMeiZuNum > mStartMeizuNum) {
                    mCurMeiZuNum = mStartMeizuNum;
                }
            }
        } else if (mCurMeiZuNum > 1) {
            mCurMeiZuNum = (int) Math.ceil((double) mCurMeiZuNum / 2);
        }

        Log.e("shuchang", "每一组的数量---->" + mCurMeiZuNum);
    }

    /**
     * 初始化每一组文件的数量
     *
     * @return
     */
    private void initMeiyizudeNum() {
        cishu = 1;
        lastTimeImageIndex = -1;//记录上一次上传成功之后最后一次的下标
        nextTimeImageIndex = -1;//记录这一组上传成功之后最后一次的下标
        mCurUploadImageSuccessIndex = -1; //记录当前上传成功的下标,当数值为lastTimeImageIndex时，开始下一组的上传

        String file_divide_num = UserHelper.getSysKeyDescValueBycode("FILE_DIVIDE_NUM");
        String file_divide_groups = UserHelper.getSysKeyDescValueBycode("FILE_DIVIDE_GROUPS");
        allFileSize = imagList.size() + vedioList.size(); //要上传的文件的整的数目
        Log.e("shuchang", "文件的总的数量---->" + allFileSize);

        int zushu = (int) Math.ceil(allFileSize / Double.valueOf(file_divide_num));
        if (zushu > Integer.parseInt(file_divide_groups)) {
            zushu = Integer.parseInt(file_divide_groups);
        }
        mCurMeiZuNum = (int) Math.ceil((double) allFileSize / zushu);

        mStartMeizuNum = mCurMeiZuNum;
    }
//    @Subscribe(threadMode = ThreadMode.MAIN)
//    public void onMessageEvent(UpLoadEvent event) {
//
//    }

    @Override
    public boolean onUnbind(Intent intent) {
       // EventBus.getDefault().unregister(this);
        return super.onUnbind(intent);

    }

}

